package cn.mazexal.examapi.services.provider;

import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Set;

import com.apple.itunes.storekit.client.GetTransactionHistoryVersion;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;
import com.apple.itunes.storekit.client.AppStoreServerAPIClient;
import com.apple.itunes.storekit.model.Environment;
import com.apple.itunes.storekit.verification.SignedDataVerifier;
import com.apple.itunes.storekit.model.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;


/**
 * 苹果服务
 *
 * @author: Mazexal
 * Date: 2025/8/20
 */
@Service
@Slf4j
public class AppleProvider {
    // 苹果支付配置参数

    // 苹果支付配置参数
    @Value("${apple.p8-file-path}")
    private String p8Path;

    @Value("${apple.key-id}")
    private String keyId;

    @Value("${apple.issuer-id}")
    private String issuerId;

    @Value("${apple.bundle-id}")
    private String bundleId;

    @Value("${apple.environment}")
    private String environment;

    @Value("${apple.root-ca-paths1}")
    private String rootCaPath1;

    @Value("${apple.root-ca-paths2}")
    private String rootCaPath2;

    @Value("${apple.root-ca-paths3}")
    private String rootCaPath3;

    @Value("${apple.apple-id}")
    private Long appleId;

    // 官方API客户端
    private AppStoreServerAPIClient apiClient;

    // 签名验证器
    private SignedDataVerifier verifier;

    /**
     * 初始化官方客户端和验证器
     */
    @PostConstruct
    public void init() {
        try {
            // 1. 读取私钥内容
            Resource resource = new ClassPathResource(p8Path);
            byte[] keyBytes = Files.readAllBytes(Paths.get(resource.getURI()));
            String privateKey = new String(keyBytes, StandardCharsets.UTF_8);


            // 2. 初始化环境
            Environment env = "PRODUCTION".equals(environment)
                    ? Environment.PRODUCTION
                    : Environment.SANDBOX;

            // 3. 创建官方API客户端
            apiClient = new AppStoreServerAPIClient(
                    privateKey,
                    keyId,
                    issuerId,
                    bundleId,
                    env
            );

            // 4. 加载苹果根证书（用于验证签名）
            Set<InputStream> rootCAs = new HashSet<>();

            Resource rootPath1 = new ClassPathResource(rootCaPath1);
            Resource rootPath2 = new ClassPathResource(rootCaPath2);
            Resource rootPath3 = new ClassPathResource(rootCaPath3);
            rootCAs.add(rootPath1.getInputStream());
            rootCAs.add(rootPath2.getInputStream());
            rootCAs.add(rootPath3.getInputStream());

            // 5. 创建签名验证器
            verifier = new SignedDataVerifier(
                    rootCAs,
                    bundleId,
                    appleId,
                    env,
                    false // 不允许使用过期证书
            );

            log.info("Apple App Store Server 客户端初始化成功（环境：{}）", environment);
        } catch (Exception e) {
            log.error("Apple App Store Server 客户端初始化失败", e);
            throw new RuntimeException("初始化苹果支付服务失败", e);
        }
    }

    /**
     * 验证并解析客户端传递的交易JWS
     * 对应StoreKit2的signedTransactionInfo
     * 这里就是交易信息
     */
    public JWSTransactionDecodedPayload verifyTransaction(String signedTransaction) throws Exception {
        Assert.hasText(signedTransaction, "signedTransaction不能为空");
        log.info("正在验证苹果交易：{}", signedTransaction);
        try {
            // 官方库验证方法：验证签名并解码
            JWSTransactionDecodedPayload payload = verifier.verifyAndDecodeTransaction(signedTransaction);

            // 额外验证：BundleID必须匹配
            if (!bundleId.equals(payload.getBundleId())) {
                throw new SecurityException("BundleID不匹配：预期=" + bundleId + "，实际=" + payload.getBundleId());
            }
            log.debug("验证成功，transactionId={}", payload.getTransactionId());
            return payload;
        } catch (Exception e) {
            log.error("交易验证失败", e);
            throw new Exception("苹果交易验证失败：" + e.getMessage(), e);
        }
    }

    /**
     * 验证并解析苹果服务器发送的通知JWS
     */
    public ResponseBodyV2DecodedPayload verifyNotification(String signedPayload) throws Exception {
        Assert.hasText(signedPayload, "signedPayload不能为空");
        try {
            // 官方库验证通知方法
            ResponseBodyV2DecodedPayload payload = verifier.verifyAndDecodeNotification(signedPayload);
            if (payload == null || payload.getData() == null) {
                throw new Exception("转换失败");
            }

            log.debug("通知验证成功，类型={}", payload.getNotificationType());
            return payload;
        } catch (Exception e) {
            log.error("通知验证失败", e);
            throw new Exception("苹果通知验证失败：" + e.getMessage(), e);
        }
    }


    /**
     * 续订信息验证
     *
     * @param signedRenewalInfo
     * @return
     * @throws Exception
     */
    public JWSRenewalInfoDecodedPayload verifyRenewalInfo(String signedRenewalInfo) throws Exception {
        Assert.hasText(signedRenewalInfo, "signedRenewalInfo不能为空");
        try {
            JWSRenewalInfoDecodedPayload payload = verifier.verifyAndDecodeRenewalInfo(signedRenewalInfo);
            log.debug("RenewalInfo验证成功，transactionId={}", payload.getAppTransactionId());
            return payload;
        } catch (Exception e) {
            log.error("RenewalInfo验证失败", e);
            throw new Exception("RenewalInfo验证失败：" + e.getMessage(), e);
        }
    }


    /**
     * 通过官方API查询交易详情
     */
    public TransactionInfoResponse queryTransaction(String transactionId) {
        Assert.hasText(transactionId, "transactionId不能为空");

        try {
            return apiClient.getTransactionInfo(transactionId);
        } catch (Exception e) {
            log.error("查询交易失败，transactionId={}", transactionId, e);
            throw new RuntimeException("查询苹果交易失败", e);
        }
    }

    public HistoryResponse getAppleOrderHis(String transactionId) throws Exception {
        try {
            TransactionHistoryRequest request = new TransactionHistoryRequest();
            request.setStartDate(0L);
            GetTransactionHistoryVersion version = GetTransactionHistoryVersion.V2;
            return apiClient.getTransactionHistory(transactionId, null, request, version);
        } catch (Exception e) {
            log.error("获取交易历史失败", e);
            throw new Exception("获取交易历史失败", e);
        }
    }

    public StatusResponse getAllActiveSubscriptionStatuses(String transactionId) throws Exception {
        try {
            return apiClient.getAllSubscriptionStatuses(transactionId, new Status[]{});
        } catch (Exception e) {
            log.error("获取所有订阅状态失败", e);
            throw new Exception("获取所有订阅状态失败", e);
        }
    }

    /**
     * 查询订阅状态
     */
    public StatusResponse querySubscriptionStatus(String originalTransactionId) {
        Assert.hasText(originalTransactionId, "originalTransactionId不能为空");

        try {
            return apiClient.getAllSubscriptionStatuses(originalTransactionId, null);
        } catch (Exception e) {
            log.error("查询订阅状态失败，originalTransactionId={}", originalTransactionId, e);
            throw new RuntimeException("查询苹果订阅状态失败", e);
        }
    }


}
